package meter

import (
	"context"
	"fmt"
	"strings"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
)

// EleMeterStateRequest represents the request parameters for electrical meter state API
// EleMeterStateRequest 表示电表状态API的请求参数
type EleMeterStateRequest struct {
}

// MeterState represents the current state information for a single electrical meter
// MeterState 表示单个电表的当前状态信息
type MeterState struct {
	ID               string `json:"id"`                 // 设备唯一ID
	Address          string `json:"address"`            // 表地址
	CollectorID      string `json:"collectorid"`        // 采集器号，NB设备采集器号与设备一致
	Description      string `json:"description"`        // 备注或设备描述信息
	C0               string `json:"c0"`                 // 电量读数0（总电量或当前电量）
	C1               string `json:"c1"`                 // 电量读数1（尖时段电量）
	C2               string `json:"c2"`                 // 电量读数2（峰时段电量）
	C3               string `json:"c3"`                 // 电量读数3（平时段电量）
	C4               string `json:"c4"`                 // 电量读数4（谷时段电量）
	Rate             string `json:"rate"`               // 费率
	RemainMoney      string `json:"remain_money"`       // 剩余金额
	Type             string `json:"type"`               // 设备号类型或其他类型标识
	PowerModifyTime  string `json:"power_modify_time"`  // 电量修改时间
	RemainModifyTime string `json:"remain_modify_time"` // 剩余金额修改时间
	UsageModifyTime  string `json:"usage_modify_time"`  // 用量修改时间
}

// EleMeterStateData represents the data section of electrical meter state response
// EleMeterStateData 表示电表状态响应的数据部分
type EleMeterStateData struct {
	Data   []MeterState `json:"data"`   // 电表状态列表
	Status int          `json:"status"` // 状态
	Total  int          `json:"total"`  // 总数
}

// EleMeterStateResponse represents the complete response from electrical meter state API
// EleMeterStateResponse 表示电表状态API的完整响应
type EleMeterStateResponse struct {
	Code    int                `json:"code"`    // 响应状态码
	Message string             `json:"message"` // 响应消息
	Data    *EleMeterStateData `json:"data"`    // 响应数据
}

// Validate validates the EleMeterStateRequest parameters using GoFrame validation
// Validate 使用GoFrame验证EleMeterStateRequest参数
func (r *EleMeterStateRequest) Validate() error {
	// Validate struct fields using GoFrame
	if err := g.Validator().Data(r).Run(context.Background()); err != nil {
		return err
	}

	return nil
}

// IsOnline checks if the meter appears to be online based on recent update times
// IsOnline 根据最近的更新时间检查电表是否在线
func (m *MeterState) IsOnline() bool {
	// A meter is considered online if it has recent power, remain, or usage modify times
	return m.PowerModifyTime != "" || m.RemainModifyTime != "" || m.UsageModifyTime != ""
}

// HasRemainMoney checks if the meter has remaining money
// HasRemainMoney 检查电表是否有剩余金额
func (m *MeterState) HasRemainMoney() bool {
	if m.RemainMoney == "" {
		return false
	}

	// Convert to float to check if greater than 0
	money := gconv.Float64(m.RemainMoney)
	return money > 0
}

// GetTotalReading returns the total power reading (C0) as float64
// GetTotalReading 返回总电量读数(C0)作为float64
func (m *MeterState) GetTotalReading() float64 {
	return gconv.Float64(m.C0)
}

// GetReadingsByTimeOfUse returns the time-of-use readings as a slice of float64
// GetReadingsByTimeOfUse 返回分时段电量读数作为float64切片
func (m *MeterState) GetReadingsByTimeOfUse() []float64 {
	return []float64{
		gconv.Float64(m.C1), // 尖时段
		gconv.Float64(m.C2), // 峰时段
		gconv.Float64(m.C3), // 平时段
		gconv.Float64(m.C4), // 谷时段
	}
}

// GetLatestUpdateTime returns the most recent update time among all modify times
// GetLatestUpdateTime 返回所有修改时间中最新的时间
func (m *MeterState) GetLatestUpdateTime() string {
	times := []string{m.PowerModifyTime, m.RemainModifyTime, m.UsageModifyTime}
	latest := ""

	for _, t := range times {
		if t != "" && (latest == "" || t > latest) {
			latest = t
		}
	}

	return latest
}

// GetDeviceTypeDescription returns a human-readable description of the device type
// GetDeviceTypeDescription 返回设备类型的可读描述
func (m *MeterState) GetDeviceTypeDescription() string {
	switch {
	case strings.HasPrefix(m.Type, "0100"):
		return "单相电表"
	case strings.HasPrefix(m.Type, "0121"):
		return "三相电表"
	case strings.HasPrefix(m.Type, "0120"):
		return "三相电表(直接接入)"
	default:
		return fmt.Sprintf("电表(类型:%s)", m.Type)
	}
}
